using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Threading;
using Services;
using SpaceBattle.Logic.SampleLevel;
using System.IO.IsolatedStorage;
using System.IO;
using Utilities.Menu.UIElements;
using SpaceBattle.Resources;

namespace SpaceBattle.Menu
{
    using Game = Microsoft.Xna.Framework.Game;

    struct StatEntry
    {
        public string Label;
        public int Offset;
        public Vector2 Position;
        public float Alpha;
    }

  public class VictoryScreen : Microsoft.Xna.Framework.DrawableGameComponent
  {
    SpriteBatch sprite_batch;
    BaseLevelStats victory_data;
    GameMode game_mode;

    ContentManager Content { get { return Game.Content; } }

    Matrix screen_transform;
    Texture2D bg, forward, backward;//, up_l_box, lo_l_box, up_r_box, lo_r_box, box_body;
    SpriteFont title_font, text_font, text_font_gt;
    StatEntry[] stat_entries;
    Button back_to_main, next_level;
    SoundEffect click;
    float wait_to_tap = 0.5f;

    public VictoryScreen(Game game, GameMode game_mode, BaseLevelStats victory_data)
      : base(game)
    {
      this.victory_data = victory_data;
      this.victory_data.TotalScore = this.victory_data.TotalScore + this.victory_data.LevelScore;
      this.game_mode = game_mode;

      stat_entries = FillStatArray();

      game.Components.Add(new InputManager(game));
    }

    private StatEntry[] FillStatArray()
    {
        int starting_x = 200, starting_y = 110, between_rows = 40;
        var ses = new StatEntry[] { 
            new StatEntry {Label = Strings.EvadedNuke + victory_data.EnemyNukesHitWithLasers, Offset = 0, 
                Position = new Vector2(starting_x, starting_y), Alpha = -0.3f},
            new StatEntry {Label = Strings.Hits, Offset = 0,
                Position = new Vector2(starting_x, starting_y + between_rows * 1), Alpha = -0.8f},
            new StatEntry {Label = Strings.Nukes + victory_data.EnemyShipsHitWithNukes, Offset = 70, 
                Position = new Vector2(starting_x + 70, starting_y + between_rows * 2), Alpha = -1.3f},
            new StatEntry {Label = Strings.Plasma + victory_data.EnemyShipsHitWithLasers, Offset = 70, 
                Position = new Vector2(starting_x + 70, starting_y + between_rows * 3), Alpha = -1.8f},
            new StatEntry {Label = Strings.LivesLost + victory_data.LivesLost, Offset = 0,
                Position = new Vector2(starting_x, starting_y + between_rows * 4), Alpha = -2.3f},
            new StatEntry {Label = Strings.PlayTime + victory_data.SecondsToCompleteLevel.ToString("#.#") + " s", Offset = 0, 
                Position = new Vector2(starting_x, starting_y + between_rows * 5), Alpha = -2.8f},
            new StatEntry {Label = Strings.LevelScore + victory_data.LevelScore, Offset = -60,
                Position = new Vector2(starting_x, starting_y + 30 + between_rows * 6), Alpha = -3.3f},
            new StatEntry {Label = Strings.TotalScore + victory_data.TotalScore, Offset = -60, 
                Position = new Vector2(450,440), Alpha = -3.8f},
        };

        return ses;
    }

    
    public override void Initialize()
    {
      var input_service = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
      input_service.OnTap += new InputManager.Tap(on_tap);

      base.Initialize();
    }

    void on_tap(Vector2 tap_position)
    {
        if (wait_to_tap <= 0.0f)
        {
            var p = tap_position.ToPoint(screen_transform);
            if (back_to_main.CollisionBox.Contains(p) && game_mode == GameMode.Campaign)
            {
                var ncs = Leaderboard.GetCampaignState();
                ncs.CampaignState.Score += victory_data.LevelScore;
                ncs.CampaignState.Credits += victory_data.Credits;
                ncs.CampaignState.Lives = victory_data.NumLivesRemaining;
                if (ncs.CampaignState.LevelPlayed < CampaignMode.NUMBER_OF_LEVELS)
                    ncs.CampaignState.LevelPlayed += 1;
                Leaderboard.SaveCampaignState(ncs);
                StateManager.SelectMenu(Game);
                click.Play(AudioManager.Volume, 0.0f, 0.0f);
            }
            else if (next_level.CollisionBox.Contains(p))
            {
                switch (game_mode)
                {
                    case GameMode.Skirmish:
                        StateManager.SelectMenu(Game);
                        break;
                    case GameMode.Campaign:
                        var ncs = Leaderboard.GetCampaignState();
                        ncs.CampaignState.Score += victory_data.LevelScore;
                        ncs.CampaignState.Credits += victory_data.Credits;
                        ncs.CampaignState.Lives = victory_data.NumLivesRemaining;
                        if (ncs.CampaignState.LevelPlayed < CampaignMode.NUMBER_OF_LEVELS)
                            ncs.CampaignState.LevelPlayed += 1;
                        Leaderboard.SaveCampaignState(ncs);
                        if (ncs.CampaignState.LevelPlayed == CampaignMode.NUMBER_OF_LEVELS) 
                            StateManager.SelectCampaignVictoryScreen(Game, victory_data); 
                        else StateManager.SelectCampaignScreen(Game, null);
                        break;
                    default:
                        StateManager.SelectMenu(Game);
                        break;
                }
                click.Play(AudioManager.Volume, 0.0f, 0.0f);
            }
        }
    }

    Rectangle box_rect;
    protected override void LoadContent()
    {
      sprite_batch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
      screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / SpaceBattleGame.DEFAULT_SCR_WIDTH, 
          GraphicsDevice.Viewport.Height / SpaceBattleGame.DEFAULT_SCR_HEIGHT, 1.0f);
      bg = Content.Load<Texture2D>("LevelFinished/victory_bg");
      forward = Content.Load<Texture2D>("Menu/button_fwd");
      backward = Content.Load<Texture2D>("Menu/button_rwd");
      title_font = Content.Load<SpriteFont>("Fonts/OCRAExtended32");
      text_font = Content.Load<SpriteFont>("Fonts/OCRAExtended24");
      text_font_gt = Content.Load<SpriteFont>("Fonts/OCRAExtended24");
      click = Game.Content.Load<SoundEffect>("Audio/button");

      box_rect = new Rectangle(34,31,411,657);

      next_level = new Button
      {
          CollisionBox = new Rectangle(GraphicsDevice.Viewport.Width - 10 - forward.Width, GraphicsDevice.Viewport.Height / 2 - forward.Height / 2,
              forward.Width, forward.Height),
          Label = "",
          Position = Vector2.Zero
      };

      back_to_main = new Button
      {
          CollisionBox = new Rectangle(10, GraphicsDevice.Viewport.Height / 2 - backward.Height / 2,
              backward.Width, backward.Height), 
          Label = "", Position = Vector2.Zero };

      title_pos = new Vector2(GraphicsDevice.Viewport.Width / 2.0f - title_font.MeasureString(Strings.Victory).X / 2.0f, 40);

      base.LoadContent();
    }

    Vector2 title_pos;
    protected override void Dispose(bool disposing)
    {
        Game.Services.RemoveService(typeof(IInputManager));

        base.Dispose(disposing);
    }

    public override void Update(GameTime gameTime)
    {
        float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

        wait_to_tap -= dt;

        for (int i = 0; i < stat_entries.Count(); i++)
        {
            stat_entries[i].Alpha = MathHelper.Clamp(stat_entries[i].Alpha + dt * 2.0f, -5.0f, 1.0f);
        }
        base.Update(gameTime);
    }

    public override void Draw(GameTime gameTime)
    {

      sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

      sprite_batch.Draw(bg, new Vector2(GraphicsDevice.Viewport.Width / 2.0f - bg.Width / 2.0f, 15), Color.White);
      sprite_batch.DrawString(title_font, Strings.Victory, title_pos, Color.White);

      for (int i = 0; i < stat_entries.Count() - 1; i++)
      {
          var str_meas = text_font.MeasureString(stat_entries[i].Label);
          sprite_batch.DrawString(text_font, stat_entries[i].Label, stat_entries[i].Position, Color.White * stat_entries[i].Alpha);
      }

      var index = stat_entries.Count() - 1;
      sprite_batch.DrawString(text_font_gt, stat_entries[index].Label, stat_entries[index].Position,
          Color.White * stat_entries[index].Alpha);

      sprite_batch.Draw(forward, next_level.CollisionBox, Color.White);

      if (game_mode == GameMode.Campaign)
          sprite_batch.Draw(backward, back_to_main.CollisionBox, Color.White);

      sprite_batch.End();

      base.Draw(gameTime);
    }
  }
}